package org.zhou.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.zhou.constant.MessageConstant;
import org.zhou.constant.StatusConstant;
import org.zhou.exception.AccountLockedException;
import org.zhou.exception.AccountNotFoundException;
import org.zhou.exception.PasswordErrorException;
import org.zhou.pojo.*;
import org.zhou.service.AdminService;
import org.zhou.utils.JwtUtil;
import org.zhou.utils.ThreadLocalUtil;

import javax.validation.constraints.Pattern;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/admin")
@Slf4j
public class AdminController {

    @Autowired
    private AdminService adminService;

//    @Autowired
//    private StringRedisTemplate stringRedisTemplate;


    /**
     * 管理员登录
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,20}$") String username, @Pattern(regexp = "^\\S{5,20}$")String password){
        //查询管理员

        log.info("员工登录：{},{}", username,password);
        Administrator admin = adminService.login(username);
        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (admin == null) {
            //账号不存在
//            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
            return Result.error(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        int count = 4-admin.getStatus();
        if (count <= StatusConstant.DISABLE) {
            //账号被锁定
//            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
            return Result.error(MessageConstant.ACCOUNT_LOCKED);
        }

        //密码比对
        // 对前端传过来的明文密码进行md5加密处理
        password = DigestUtils.md5DigestAsHex(password.getBytes());

        if (!password.equals(admin.getPassword())) {
            //密码错误
//            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);


            adminService.updateStatus(admin.getStatus()+1,admin.getUsername());
            return Result.error(MessageConstant.PASSWORD_ERROR+",还可以尝试"+count+"次");
        }

        //登录成功后，修改状态为0
        adminService.updateStatus(0,admin.getUsername());
        //生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", admin.getId());
        claims.put("username", admin.getUsername());

        String token = JwtUtil.getToken(claims);
        log.info("jwt:{}",token);
        return Result.success(token);

    }

    /**
     * 注册
     * @param username
     * @param password
     * @param rePassword
     * @return
     */
    @PostMapping("/register")
    public Result<String> register(String username, String password, String rePassword){
        //查询管理员
        if (!StringUtils.hasLength(password) || !StringUtils.hasLength(rePassword) ||username.length()>20 || username.length()<6) {
            return Result.error("注册失败");
        }
        log.info("员工注册：{},{},{}", username,password,rePassword);
        Administrator admin = adminService.login(username);
        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (admin != null) {
            //账号不存在
//            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
            return Result.error("该账号已存在");
        }
        if(!password.equals(rePassword)){
            return Result.error("密码不一致");
        }


        // 对前端传过来的明文密码进行md5加密处理
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        adminService.addAdmin(username,password);
        return Result.success();

    }


    /**
     *
     * @param
     * @return
     */
    @GetMapping("/adminInfo")
    public Result<Administrator> userInfo(/*@RequestHeader(name = "token") String token*/){
//        Map<String, Object> map = JwtUtil.parseToken(token);
//        String username = (String) map.get("username");

        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        log.info("查询管理员姓名,{}",username);

        Administrator admin = adminService.login(username);
        return Result.success(admin);

    }

    /**
     * 修改基本信息
     * @param admin
     * @return
     */
    @PutMapping("/updateInfo")
    public Result updateAdmin(@RequestBody Administrator admin){
        log.info("修改基本信息，{}",admin);
        if(admin.getName().length()>20||admin.getName().length()<2){
            return Result.error(MessageConstant.ERROR);
        }

        if(!admin.getPhone().matches(MessageConstant.PATTERN_PHONE)){
            return Result.error(MessageConstant.ERROR);
        }
        adminService.updateInfo(admin);
        return Result.success();
    }

    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String, String> params,@RequestHeader("token") String token) {
        //1.校验参数
        String oldPwd = params.get("oldPassword");
        String newPwd = params.get("newPassword1");
        String rePwd = params.get("newPassword2");
        log.info("修改密码：{},{},{},{}",oldPwd,newPwd,rePwd,token);

        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            return Result.error("修改失败");
        }

        //原密码是否正确
        //调用userService根据用户名拿到原密码,再和old_pwd比对
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        Administrator loginUser = adminService.login(username);
        oldPwd = DigestUtils.md5DigestAsHex(oldPwd.getBytes());
        if (!loginUser.getPassword().equals(oldPwd)){
            return Result.error("原密码填写不正确");
        }

        //newPwd和rePwd是否一样
        if (!rePwd.equals(newPwd)){
            return Result.error("两次填写的新密码不一样");
        }


        //2.调用service完成密码更新
        newPwd = DigestUtils.md5DigestAsHex(newPwd.getBytes());
        adminService.updatePwd(newPwd);
        //删除redis中对应的token
//        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
//        operations.getOperations().delete(token);
        return Result.success();
    }

    @GetMapping("/reader")
    public Result<PageResult> readerList(
            Integer pageNum,
            Integer pageSize,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) Integer state,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) String readerId
    ) {
        log.info("分页查询读者，{},{},{},{},{},{}",pageNum,pageSize,name,state,phone,readerId);
        PageResult pb =  adminService.readerList(pageNum,pageSize,name,state,phone,readerId);
        return Result.success(pb);
    }

    @PostMapping("/addReader")
    public Result addReader(@RequestBody Readers readers){
        log.info("添加读者，{}",readers);
        if(readers.getName().length()>20 || readers.getName().length()==0){
            return Result.error(MessageConstant.ERROR);
        }

        if(!readers.getPhone().matches(MessageConstant.PATTERN_PHONE)){
            return Result.error(MessageConstant.ERROR);
        }
        List readerList = adminService.readerList(1,1,null,null,null,readers.getIdNumber())
                .getItems();
        if(readerList.size() > 0){
            return Result.error("该编号已存在");
        }
        adminService.addReader(readers);
        return Result.success();
    }

    @PutMapping("/updateReader")
    public Result updateBook(@RequestBody Readers readers){
        log.info("修改读者，{}",readers);
        if(readers.getName().length()>20 || readers.getName().length()==0){
            return Result.error(MessageConstant.ERROR);
        }
        if(!readers.getPhone().matches(MessageConstant.PATTERN_PHONE)){
            return Result.error(MessageConstant.ERROR);
        }

        adminService.updateReader(readers);
        return Result.success();
    }

}
